package com.recursivechaos.gamemaster.dao;

import java.util.List;
import java.util.Random;

import org.hibernate.HibernateException;

import com.recursivechaos.gamemaster.classes.RaceObj;
import com.recursivechaos.gamemaster.exception.GameException;

public class RaceObjDAO extends DAO {
	/**
	 * Given the exact string name of a race, returns the race object
	 * 
	 * @param raceString
	 *            Exact string of race
	 * @return Race object matching the string
	 * @throws GameException
	 *             Error loading all data from race
	 *             
	 */
	private RaceObj findRaceInExactString(String raceString)
			throws GameException {
		RaceObj foundRace;
		try {
			begin();
			foundRace = (RaceObj) getSession().get(RaceObj.class, raceString);
			commit();
		} catch (HibernateException e) {
			rollback();
			throw new GameException("Could not get race details.");
		} finally {
			close();
		}
		return foundRace;
	}

	/**
	 * Returns the character race from an input string, used in the character
	 * creation input parsing
	 * 
	 * @param input
	 *            Input string (possibly) containing a race
	 * @return Race object found in string
	 * @throws GameException
	 */
	public RaceObj findRaceInString(String input) throws GameException {
		RaceObj foundRace;
		// Find if string contains a race
		String raceString = "";
		List<String> raceList = getRaceStringList();
		for (int i = 0; i < raceList.size(); i++) {
			String rname = raceList.get(i);
			if (input.contains(rname.toUpperCase())) {
				if (raceString.equals("")) {
					raceString = raceList.get(i);
				} else {
					throw new GameException("Multiracing not allowed.");
				}
			}
		}
		if (raceString.equals("")) {
			throw new GameException("No race found.");
		}
		// Once we've checked the input for a race, we get the object
		foundRace = getRaceFromString(raceString);

		return foundRace;
	}

	/**
	 * Get race object from exact string
	 * 
	 * @param raceString
	 *            String of race object
	 * @return RaceObj matching the string
	 * @throws GameException
	 */
	private RaceObj getRaceFromString(String raceString) throws GameException {
		try {
			begin();
			RaceObj foundRace = (RaceObj) getSession().get(RaceObj.class,
					raceString);
			commit();
			return foundRace;
		} catch (HibernateException e) {
			rollback();
			throw new GameException("That is not a valid race.");
		} finally {
			close();
		}
	}

	/**
	 * Get a List<String> of available races
	 * 
	 * @return List<String> of races
	 */
	@SuppressWarnings("unchecked")
	public List<String> getRaceStringList() {
		List<String> raceList = null;
		try {
			begin();
			raceList = getSession().createSQLQuery(
					"SELECT RACE_NAME FROM recursi3_igm_db.raceobjs;").list();
			commit();
		} catch (Exception e) {
			rollback();
		} finally {
			close();
		}
		return raceList;
	}

	/**
	 * Get a random race
	 * 
	 * @return RaceObj of a random race
	 * @throws GameException
	 */
	public RaceObj getRandomRace() throws GameException {
		List<String> raceList = getRaceStringList();
		RaceObj foundRace;
		Random generator = new Random();
		int r = generator.nextInt(raceList.size());
		String randRace = raceList.get(r);
		foundRace = findRaceInExactString(randRace);
		return foundRace;
	}

}
